﻿#include "FITKAbaStepRelatedDataObject.h"
#include "FITKAbaStepManager.h"
#include "FITK_Kernel/FITKCore/FITKAbstractDataObject.h"
#include "FITK_Kernel/FITKCore/FITKDataRepo.h"

bool Interface::FITKAbaStepRelatedDataObject::isValidInStep(int stepId /*= 0*/)
{
    return true;
}

Interface::FITKAbaStepEnum::StateInStep Interface::FITKAbaStepRelatedDataObject::getStateInStep(int stepId)
{    
    //数据创建所在的分析步索引
    int createdStepIndex = this->getStepIndex(m_createdStepId);
    if (createdStepIndex == -1)
        return FITKAbaStepEnum::StateInStep::None;
    //要判断状态的step的索引
    int stepIndex = this->getStepIndex(stepId);
    //数据对象被取消激活的step的索引
    int deactiveIndex = this->getStepIndex(m_deactiveStepId);
    //manager中不存在该step，则返回无状态
    if (stepIndex == -1)
        return FITKAbaStepEnum::StateInStep::None;
    //如果要判断状态的step在创建所在的step之前，则返回无状态
    if (stepIndex < createdStepIndex)
        return FITKAbaStepEnum::StateInStep::None;
    //要判断状态的step就是创建所在的step，则返回Created状态
    if (stepIndex == createdStepIndex)
        return FITKAbaStepEnum::StateInStep::Created;
    //要判断状态的step在创建所在的step之后
    if (!this->isValidInStep(stepId))
        return FITKAbaStepEnum::StateInStep::InValid;
    //不存在取消激活的step，则根据数据是否更改返回Modified或Propagated或BuiltIntoBaseState状态
    if (deactiveIndex == -1)
    {
        //判断分析步Perturbation性质是否发生变化
        if (this->isStepPerturbationChanged(stepId))
        {
            if (this->isReValid(stepId))
                return this->isModifiedInStep(stepId) ? 
                FITKAbaStepEnum::StateInStep::Modified : FITKAbaStepEnum::StateInStep::Propagated;
            return FITKAbaStepEnum::StateInStep::BuiltIntoBaseState;
        }
        return this->isModifiedInStep(stepId) ? 
            FITKAbaStepEnum::StateInStep::Modified : FITKAbaStepEnum::StateInStep::Propagated;
    }
    //存在取消激活的step
    //要判断状态的step在取消激活的step之后，则返回NoLongerActive状态
    if (stepIndex > deactiveIndex)
        return FITKAbaStepEnum::StateInStep::NoLongerActive;
    //要判断状态的step就是取消激活的step，则返回Deactive状态
    else if (stepIndex == deactiveIndex)
        return FITKAbaStepEnum::StateInStep::Deactived;
    else//要判断状态的step在取消激活的step之前，则根据数据是否更改返回Modified或Propagated或BuiltIntoBaseState状态
    {
        if (this->isStepPerturbationChanged(stepId))
            return FITKAbaStepEnum::StateInStep::BuiltIntoBaseState;
        return this->isModifiedInStep(stepId) ? 
            FITKAbaStepEnum::StateInStep::Modified : FITKAbaStepEnum::StateInStep::Propagated;
    }
}

void Interface::FITKAbaStepRelatedDataObject::setCreatedStep(int stepId)
{
    m_createdStepId = stepId;
}

int Interface::FITKAbaStepRelatedDataObject::getCreatedStep() const
{
    return m_createdStepId;
}

void Interface::FITKAbaStepRelatedDataObject::setDeactiveStep(int stepId)
{
    m_deactiveStepId = stepId;
    this->activeStateChanged();
}

int Interface::FITKAbaStepRelatedDataObject::getDeactiveStep() const
{
    return m_deactiveStepId;
}

void Interface::FITKAbaStepRelatedDataObject::setActive()
{
    m_deactiveStepId = -1;
    this->activeStateChanged();
}

bool Interface::FITKAbaStepRelatedDataObject::isValidInCreatedStep()
{
    return true;
}

int Interface::FITKAbaStepRelatedDataObject::getStepIndex(int stepId)
{
    if (!this->hasGetStepManager())
        return -1;
    QVector<int> stepIds = this->getStepIds();
    int index = stepIds.indexOf(stepId);
    return index;
}

int Interface::FITKAbaStepRelatedDataObject::getStepIdByIndex(int index)
{
    if (!this->hasGetStepManager())
        return -1;
    auto data = m_stepManager->getDataByIndex(index);
    if (data == nullptr)
        return -1;
    return data->getDataObjectID();
}

bool Interface::FITKAbaStepRelatedDataObject::isStepPerturbationChanged(int stepId)
{
    if (!this->hasGetStepManager())
        return false;
    int index = this->getStepIndex(stepId);
    if (index <= 0)
        return false;
    FITKAbaAbstractStep* preStep = m_stepManager->getDataByIndex(index - 1);
    FITKAbaAbstractStep* step = m_stepManager->getDataByIndex(index);
    if (preStep == nullptr || step == nullptr)
        return false;
    //判断分析步
    if (preStep->isPerturbation() != step->isPerturbation())
        return true;
    return false;
}

bool Interface::FITKAbaStepRelatedDataObject::isReValid(int stepId)
{
    if (!this->hasGetStepManager())
        return false;
    int index = this->getStepIndex(stepId);
    if (index <= 0)
        return false;
    FITKAbaAbstractStep* preStep = m_stepManager->getDataByIndex(index - 1);
    FITKAbaAbstractStep* step = m_stepManager->getDataByIndex(index);
    if (preStep == nullptr || step == nullptr)
        return false;
    //判断数据是否从无效变为有效
    if (!this->isValidInStep(preStep->getDataObjectID()))
        return true;
    return false;
}

QVector<int> Interface::FITKAbaStepRelatedDataObject::getStepIds()
{
    if (!this->hasGetStepManager())
        return{};
    int count = m_stepManager->getDataCount();
    QVector<int> stepIds{};
    for (int i = 0; i < count; ++i)
    {
        stepIds.push_back(m_stepManager->getDataByIndex(i)->getDataObjectID());
    }
    return stepIds;
}

Interface::FITKAbaStepManager* Interface::FITKAbaStepRelatedDataObject::getStepManager(Core::FITKAbstractDataObject* obj) const
{
    if (obj == nullptr) return nullptr;
    int pid = obj->getDataObjectID();
    Core::FITKAbstractDataObject* cobj = nullptr;
    //寻找case data
    while (pid >0)
    {
        cobj = FITKDATAREPO->getDataByID(pid);
        if(cobj == nullptr) return nullptr;
        //caseData 类名标记
        if (cobj->getClassName() == "AbaqusData::FITKDataCase") 
            break;
        //向上寻找
        pid = cobj->getParentDataID();
    }
    //错误值，未找到
    if (pid <= 0 || cobj == nullptr) return nullptr;
    //从数据中找到算例管理器标记
    auto s = cobj->getUserDataT<Core::FITKAbstractObject*>(Core::FITKUserRole + 4);
    if (s == nullptr) return nullptr;
    //强制类型转换
    return dynamic_cast<Interface::FITKAbaStepManager*>(s);
}
